#include "libGeoutils/shape/Polyline.h"
#include "nlohmann/json.hpp"
#include <sstream>

#define COORDS_KEY "coords"

geo::shape::Polyline::Polyline()
{
}

geo::shape::Polyline::Polyline(const std::vector<Coord::sptr>& coords)
	: mCoords(coords)
{
}

geo::shape::Polyline::~Polyline()
{
}

bool geo::shape::Polyline::appendCoord(Coord::sptr spCoord)
{
	mCoords.push_back(spCoord);
	return true;
}

std::vector<geo::shape::Coord::sptr> geo::shape::Polyline::getCoords() const 
{ 
	return mCoords; 
}

geo::shape::Coord::Coord::sptr geo::shape::Polyline::getCoordIndexAt(unsigned int index) const
{
	if (index < mCoords.size()) {
		return mCoords[index];
	}
	return Coord::sptr();
}

bool geo::shape::Polyline::to_string(std::string& out_str) const
{
	std::stringstream ss;
	Properties::to_string(out_str);
	ss << out_str;

	ss << "Polyline: [\n";
	for (size_t i = 0; i < mCoords.size(); ++i) {
		if (mCoords[i]) {
			ss << "(" << mCoords[i]->getLongitude() << ", " << mCoords[i]->getLatitude() << ")";
			if (i != mCoords.size() - 1) {
				ss << ", ";
			} ss << "\n";
		}
	}
	ss << "]";
	out_str = ss.str();
	return true;
}

bool geo::shape::Polyline::to_json(std::string& out_str) const
{
	nlohmann::json json;
	nlohmann::json json_coords;

	try
	{
		std::string loop_op_str;
		nlohmann::json loop_json_obj;
		for (const auto& loop_coord : mCoords) {
			if (loop_coord && loop_coord->to_json(loop_op_str)) {
				loop_json_obj = nlohmann::json::parse(loop_op_str);
				json_coords.push_back(loop_json_obj);
			}
		}

		json[COORDS_KEY] = json_coords;
		out_str = json.dump();
		return true;
	}
	catch (const std::exception&)
	{
		mLastErrorMessage = "catch one error!";
		return false;
	}
}

bool geo::shape::Polyline::from_json(const std::string& in_str)
{
	return true;
}
